<template>
  <div class="game-2048">
    <div class="game-header">
      <div class="scores-container">
        <div class="score-container">
          <div class="score-title">得分</div>
          <div class="score">{{ score }}</div>
        </div>
        <div class="best-container">
          <div class="score-title">最高分</div>
          <div class="score">{{ bestScore }}</div>
        </div>
      </div>
      <div class="game-intro">
        <div class="restart-button" @click="restartGame">重新开始</div>
        <div class="game-explanation">
          <strong>玩法:</strong> 使用方向键或滑动合并相同数字，得到2048!
        </div>
      </div>
    </div>

    <div class="game-container">
      <div class="game-message" v-if="gameOver || gameWon">
        <p v-if="gameWon">你赢了!</p>
        <p v-else>游戏结束!</p>
        <div class="lower">
          <a class="retry-button" @click="restartGame">再试一次</a>
        </div>
      </div>

      <div class="grid-wrapper">
        <div class="grid-container">
          <div class="grid-row" v-for="(row, rowIndex) in grid" :key="rowIndex">
            <div 
              class="grid-cell" 
              v-for="(cell, cellIndex) in row" 
              :key="cellIndex"
              :class="{ 'tile-2': cell === 2, 'tile-4': cell === 4, 'tile-8': cell === 8, 'tile-16': cell === 16, 
                       'tile-32': cell === 32, 'tile-64': cell === 64, 'tile-128': cell === 128, 
                       'tile-256': cell === 256, 'tile-512': cell === 512, 'tile-1024': cell === 1024, 
                       'tile-2048': cell === 2048, 'tile-super': cell > 2048 }"
            >
              {{ cell ? cell : '' }}
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- <div class="game-controls">
      <div class="control-row">
        <div class="control-button" @click="move('up')">↑</div>
      </div>
      <div class="control-row">
        <div class="control-button" @click="move('left')">←</div>
        <div class="control-button" @click="move('down')">↓</div>
        <div class="control-button" @click="move('right')">→</div>
      </div>
    </div> -->
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

// 游戏状态
const grid = ref([
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [0, 0, 0, 0]
]);
const score = ref(0);
const bestScore = ref(0);
const gameOver = ref(false);
const gameWon = ref(false);
let touchStartX = 0;
let touchStartY = 0;

// 初始化游戏
const initGame = () => {
  // 清空网格
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      grid.value[i][j] = 0;
    }
  }
  
  // 添加两个初始方块
  addRandomTile();
  addRandomTile();
  
  // 重置游戏状态
  score.value = 0;
  gameOver.value = false;
  gameWon.value = false;
  
  // 从本地存储加载最高分
  const savedBestScore = localStorage.getItem('game2048BestScore');
  if (savedBestScore) {
    bestScore.value = parseInt(savedBestScore);
  }
};

// 添加随机方块
const addRandomTile = () => {
  const emptyCells = [];
  
  // 找出所有空单元格
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid.value[i][j] === 0) {
        emptyCells.push({ row: i, col: j });
      }
    }
  }
  
  // 如果有空单元格，随机选择一个并添加2或4
  if (emptyCells.length > 0) {
    const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
    grid.value[randomCell.row][randomCell.col] = Math.random() < 0.9 ? 2 : 4;
  }
};

// 检查游戏是否结束
const checkGameOver = () => {
  // 检查是否有空单元格
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid.value[i][j] === 0) {
        return false;
      }
    }
  }
  
  // 检查是否有可以合并的相邻单元格
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 3; j++) {
      if (grid.value[i][j] === grid.value[i][j + 1]) {
        return false;
      }
    }
  }
  
  for (let j = 0; j < 4; j++) {
    for (let i = 0; i < 3; i++) {
      if (grid.value[i][j] === grid.value[i + 1][j]) {
        return false;
      }
    }
  }
  
  // 如果没有空单元格且没有可合并的单元格，游戏结束
  return true;
};

// 检查是否获胜
const checkWin = () => {
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid.value[i][j] === 2048) {
        return true;
      }
    }
  }
  return false;
};

// 移动和合并方块
const move = (direction) => {
  if (gameOver.value || gameWon.value) return;
  
  let moved = false;
  
  // 创建网格的深拷贝用于比较
  const oldGrid = JSON.parse(JSON.stringify(grid.value));
  
  if (direction === 'up') {
    for (let j = 0; j < 4; j++) {
      let column = [grid.value[0][j], grid.value[1][j], grid.value[2][j], grid.value[3][j]];
      let result = moveAndMerge(column);
      
      for (let i = 0; i < 4; i++) {
        grid.value[i][j] = result[i];
      }
    }
  } else if (direction === 'down') {
    for (let j = 0; j < 4; j++) {
      let column = [grid.value[0][j], grid.value[1][j], grid.value[2][j], grid.value[3][j]];
      let result = moveAndMerge(column.reverse()).reverse();
      
      for (let i = 0; i < 4; i++) {
        grid.value[i][j] = result[i];
      }
    }
  } else if (direction === 'left') {
    for (let i = 0; i < 4; i++) {
      let row = [...grid.value[i]];
      let result = moveAndMerge(row);
      grid.value[i] = result;
    }
  } else if (direction === 'right') {
    for (let i = 0; i < 4; i++) {
      let row = [...grid.value[i]];
      let result = moveAndMerge(row.reverse()).reverse();
      grid.value[i] = result;
    }
  }
  
  // 检查是否有移动
  moved = JSON.stringify(grid.value) !== JSON.stringify(oldGrid);
  
  if (moved) {
    addRandomTile();
    
    // 检查是否获胜
    if (checkWin()) {
      gameWon.value = true;
    }
    
    // 检查游戏是否结束
    if (checkGameOver()) {
      gameOver.value = true;
    }
    
    // 更新最高分
    if (score.value > bestScore.value) {
      bestScore.value = score.value;
      localStorage.setItem('game2048BestScore', bestScore.value.toString());
    }
  }
};

// 移动和合并一行或一列
const moveAndMerge = (line) => {
  // 移除所有零
  let nonZeros = line.filter(cell => cell !== 0);
  
  // 合并相同的数字
  for (let i = 0; i < nonZeros.length - 1; i++) {
    if (nonZeros[i] === nonZeros[i + 1]) {
      nonZeros[i] *= 2;
      score.value += nonZeros[i];
      nonZeros.splice(i + 1, 1);
    }
  }
  
  // 填充零
  while (nonZeros.length < 4) {
    nonZeros.push(0);
  }
  
  return nonZeros;
};

// 重新开始游戏
const restartGame = () => {
  initGame();
};

// 处理键盘事件
const handleKeyDown = (e) => {
  if (e.key === 'ArrowUp') {
    move('up');
    e.preventDefault();
  } else if (e.key === 'ArrowDown') {
    move('down');
    e.preventDefault();
  } else if (e.key === 'ArrowLeft') {
    move('left');
    e.preventDefault();
  } else if (e.key === 'ArrowRight') {
    move('right');
    e.preventDefault();
  }
};

// 处理触摸事件
const handleTouchStart = (e) => {
  touchStartX = e.touches[0].clientX;
  touchStartY = e.touches[0].clientY;
};

const handleTouchEnd = (e) => {
  if (!touchStartX || !touchStartY) return;
  
  const touchEndX = e.changedTouches[0].clientX;
  const touchEndY = e.changedTouches[0].clientY;
  
  const dx = touchEndX - touchStartX;
  const dy = touchEndY - touchStartY;
  
  // 确定是水平还是垂直滑动
  if (Math.abs(dx) > Math.abs(dy)) {
    if (dx > 20) {
      move('right');
    } else if (dx < -20) {
      move('left');
    }
  } else {
    if (dy > 20) {
      move('down');
    } else if (dy < -20) {
      move('up');
    }
  }
  
  touchStartX = 0;
  touchStartY = 0;
};

// 组件挂载时
onMounted(() => {
  initGame();
  window.addEventListener('keydown', handleKeyDown);
  document.querySelector('.game-container').addEventListener('touchstart', handleTouchStart, { passive: true });
  document.querySelector('.game-container').addEventListener('touchend', handleTouchEnd);
});

// 组件卸载时
onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown);
  const gameContainer = document.querySelector('.game-container');
  if (gameContainer) {
    gameContainer.removeEventListener('touchstart', handleTouchStart);
    gameContainer.removeEventListener('touchend', handleTouchEnd);
  }
});

// 导出方法供父组件使用
defineExpose({
  restartGame
});
</script>

<style scoped>
.game-2048 {
  width: 100%;
  height: auto;
  margin: 0 auto;
  background: #faf8ef;
  padding: 8px;
  box-sizing: border-box;
  overflow: visible;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.game-header {
  display: flex;
  flex-direction: column;
  margin-bottom: 10px;
  width: 100%;
}

.scores-container {
  display: flex;
  justify-content: space-between;
  margin-bottom: 16px;
}

.score-container, .best-container {
  background: #bbada0;
  padding: 8px 16px;
  border-radius: 6px;
  color: white;
  text-align: center;
  min-width: 80px;
}

.score-title {
  font-size: 14px;
  opacity: 0.7;
}

.score {
  font-size: 20px;
  font-weight: bold;
}

.game-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.restart-button {
  background: #8f7a66;
  color: white;
  padding: 8px 16px;
  border-radius: 6px;
  font-weight: bold;
  cursor: pointer;
  margin-bottom: 8px;
}

.game-explanation {
  font-size: 14px;
  color: #776e65;
  text-align: center;
}

.game-container {
  position: relative;
  background: #bbada0;
  border-radius: 8px;
  padding: 8px;
  margin-bottom: 10px;
  touch-action: none;
  width: 100%;
  box-sizing: border-box;
  overflow: visible;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  max-height: 60vh;
}

.grid-wrapper {
  width: 100%;
  max-width: 280px;
  aspect-ratio: 1/1;
  margin: 0 auto;
  flex-shrink: 0;
}

.game-message {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(238, 228, 218, 0.73);
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  border-radius: 8px;
}

.game-message p {
  font-size: 24px;
  font-weight: bold;
  color: #776e65;
  margin-bottom: 16px;
}

.retry-button {
  background: #8f7a66;
  color: white;
  padding: 8px 16px;
  border-radius: 6px;
  font-weight: bold;
  cursor: pointer;
}

.grid-container {
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  grid-gap: 8px;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  background: #bbada0;
  border-radius: 6px;
  padding: 8px;
}

.grid-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 8px;
  width: 100%;
}

.grid-cell {
  width: 100%;
  aspect-ratio: 1/1;
  background: #cdc1b4;
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 24px;
  font-weight: bold;
  color: #776e65;
  box-sizing: border-box;
  -webkit-user-select: none;
  user-select: none;
}

.tile-2 {
  background: #eee4da;
}

.tile-4 {
  background: #ede0c8;
}

.tile-8 {
  background: #f2b179;
  color: white;
}

.tile-16 {
  background: #f59563;
  color: white;
}

.tile-32 {
  background: #f67c5f;
  color: white;
}

.tile-64 {
  background: #f65e3b;
  color: white;
}

.tile-128 {
  background: #edcf72;
  color: white;
  font-size: 20px;
}

.tile-256 {
  background: #edcc61;
  color: white;
  font-size: 20px;
}

.tile-512 {
  background: #edc850;
  color: white;
  font-size: 20px;
}

.tile-1024 {
  background: #edc53f;
  color: white;
  font-size: 16px;
}

.tile-2048 {
  background: #edc22e;
  color: white;
  font-size: 16px;
}

.tile-super {
  background: #3c3a32;
  color: white;
  font-size: 14px;
}

.game-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 10px;
  margin-bottom: 10px;
  flex-shrink: 0;
}

.control-row {
  display: flex;
  justify-content: center;
  margin-bottom: 8px;
  width: 100%;
  max-width: 200px;
}

.control-button {
  width: 45px;
  height: 45px;
  background: #8f7a66;
  color: white;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 22px;
  margin: 0 4px;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

@media (max-width: 480px) {
  .grid-cell {
    font-size: 20px;
  }
  
  .tile-128, .tile-256, .tile-512 {
    font-size: 18px;
  }
  
  .tile-1024, .tile-2048 {
    font-size: 14px;
  }
}
</style>
